package com.ssy.lingxi.marketing.serviceimpl.component.coupon;

import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.constant.member.AbilitySuitableMemberEnum;
import com.ssy.lingxi.common.constant.member.PlatformSuitableMemberEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.marketing.entity.coupon.*;
import com.ssy.lingxi.marketing.model.bo.AtCanReceiveSuitableMemberBO;
import com.ssy.lingxi.marketing.model.bo.PfCanReceiveSuitableMemberBO;
import com.ssy.lingxi.marketing.model.constant.*;
import com.ssy.lingxi.marketing.repository.CouponMemberLevelRepository;
import com.ssy.lingxi.marketing.repository.CouponShopRepository;
import com.ssy.lingxi.marketing.repository.MerchantCouponDetailRepository;
import com.ssy.lingxi.marketing.repository.PlatformCouponDetailRepository;
import com.ssy.lingxi.marketing.serviceimpl.component.SuitableFieldComponent;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.AtSubMemberSuitableMemberVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.PfSubMemberSuitableMemberVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.Objects;

/**
 * 优惠券领取规则校验组件
 * @author yzc
 * @version 2.0.0
 * @date 2021/9/17
 */
@Slf4j
@Component
public class CouponReceiveCheckRuleComponent {

    @Resource
    private CouponMemberLevelRepository couponMemberLevelRepository;
    @Resource
    private MerchantCouponDetailRepository merchantCouponDetailRepository;
    @Resource
    private PlatformCouponDetailRepository platformCouponDetailRepository;
    @Resource
    private CouponShopRepository couponShopRepository;
    @Resource
    private CouponCacheComponent couponCacheComponent;

    // ===========================平台===========================

    /**
     * @see #baseCheckPlatformCanReceiveComplete
     */
    public CanReceiveEnum checkPlatformCanReceiveComplete(UserLoginCacheDTO loginUser, PlatformCouponDO platformCouponDO, Long shopId, PfSubMemberSuitableMemberVO subMemberSuitableMemberVO) {
        PfCanReceiveSuitableMemberBO pfCanReceiveSuitableMemberBO = this.baseCheckPlatformCanReceiveComplete(loginUser, platformCouponDO, shopId, subMemberSuitableMemberVO);
        return pfCanReceiveSuitableMemberBO.getCanReceive();
    }

    /**
     * 校验平台优惠券是否可领取
     * 如果有领取且未使用,则会直接返回已领取
     * 如果登录了则会校验会员的等级规则,否则不校验
     * @param loginUser 登录用户信息
     * @param platformCouponDO 平台优惠券
     * @param shopId 商城id
     * @param subMemberSuitableMemberVO 适用会员等级信息
     * @return PfCanReceiveSuitableMemberBO 领取判断结果, 匹配到的适用会员
     */
    public PfCanReceiveSuitableMemberBO baseCheckPlatformCanReceiveComplete(UserLoginCacheDTO loginUser, PlatformCouponDO platformCouponDO, Long shopId, PfSubMemberSuitableMemberVO subMemberSuitableMemberVO) {
        PfCanReceiveSuitableMemberBO pfCanReceiveSuitableMemberBO = new PfCanReceiveSuitableMemberBO();

        // 是否登录
        if (Objects.isNull(loginUser)) {
            pfCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_LOGIN);
            return pfCanReceiveSuitableMemberBO;
        }

        // 判断优惠券基本规则
        if (!checkPlatformCouponBaseRule(platformCouponDO)) {
            pfCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return pfCanReceiveSuitableMemberBO;
        }

        // 判断优惠券商城规则
        if (!checkPlatformCouponShopRule(platformCouponDO, shopId)) {
            pfCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return pfCanReceiveSuitableMemberBO;
        }

        // 判断会员等级规则
        PlatformSuitableMemberEnum platformSuitableMemberEnum = checkPlatformMemberLevelRule(platformCouponDO, subMemberSuitableMemberVO);
        if (Objects.isNull(platformSuitableMemberEnum)) {
            pfCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return pfCanReceiveSuitableMemberBO;
        }

        // 判断会员领取记录
        CanReceiveEnum canReceiveEnum = checkPlatformReceiveDetailComplete(loginUser, platformCouponDO);
        pfCanReceiveSuitableMemberBO.setCanReceive(canReceiveEnum);
        pfCanReceiveSuitableMemberBO.setSuitableMember(platformSuitableMemberEnum);
        return pfCanReceiveSuitableMemberBO;
    }

    /**
     * 校验平台优惠券是否可领取
     * 如果登录了则会校验会员的等级规则,否则不校验
     * @param loginUser 登录用户信息
     * @param platformCouponDO 平台优惠券
     * @param shopId 商城id
     * @param subMemberSuitableMemberVO 适用会员等级信息
     * @return 是否可领取 true, false
     */
    public boolean checkPlatformCanReceive(UserLoginCacheDTO loginUser, PlatformCouponDO platformCouponDO, Long shopId, PfSubMemberSuitableMemberVO subMemberSuitableMemberVO) {
        // 是否登录
        if (Objects.isNull(loginUser)) {
            return false;
        }

        // 判断优惠券基本规则
        if (!checkPlatformCouponBaseRule(platformCouponDO)) {
            return false;
        }

        // 判断优惠券商城规则
        if (!checkPlatformCouponShopRule(platformCouponDO, shopId)) {
            return false;
        }

        // 判断会员等级规则
        PlatformSuitableMemberEnum platformSuitableMemberEnum = checkPlatformMemberLevelRule(platformCouponDO, subMemberSuitableMemberVO);
        if (Objects.isNull(platformSuitableMemberEnum)) {
            return false;
        }

        // 判断会员领取记录
        return checkPlatformMemberReceiveDetailRule(loginUser.getMemberId(), loginUser.getMemberRoleId(), platformCouponDO);
    }

    /**
     * 校验平台优惠券的基本规则(前台用户领取)
     * @param platformCouponDO 平台优惠券
     * @return true, false
     */
    public boolean checkPlatformCouponBaseRule(PlatformCouponDO platformCouponDO) {
        long currentTimeMillis = System.currentTimeMillis();
        // 执行中
        if (!PlatformCouponStatusEnum.EXECUTING.getCode().equals(platformCouponDO.getStatus())) {
            return false;
        }
        // 在发券时间内
        if (platformCouponDO.getReleaseTimeStart() > currentTimeMillis || platformCouponDO.getReleaseTimeEnd() < currentTimeMillis) {
            return false;
        }
        // 前台用户领取
        if (!PlatformCouponGetWayEnum.FRONT.getCode().equals(platformCouponDO.getGetWay())) {
            return false;
        }
        // 领取条件
        if (Objects.isNull(platformCouponDO.getConditionGetTotal()) || Objects.isNull(platformCouponDO.getConditionGetDay())) {
            return false;
        }
        // 剩余领取数需大于0
        if (platformCouponDO.getQuantity() - couponCacheComponent.getCouponObtainQuantity(BelongTypeEnum.PLATFORM, platformCouponDO.getId()) <= 0) {
            return false;
        }

        return true;
    }

    /**
     * 校验平台优惠券的基本规则(指定会员领取)
     * @param platformCouponDO 平台优惠券
     * @return true, false
     */
    public Wrapper<Void> checkPlatformAppointCouponBaseRule(PlatformCouponDO platformCouponDO) {
        long currentTimeMillis = System.currentTimeMillis();
        // 执行中
        if (!PlatformCouponStatusEnum.EXECUTING.getCode().equals(platformCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        // 在发券时间内
        if (platformCouponDO.getReleaseTimeStart() > currentTimeMillis || platformCouponDO.getReleaseTimeEnd() < currentTimeMillis) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_CURRENT_TIME_NOT_IN_RELEASE_TIME);
        }
        // 指定会员领取
        if (!PlatformCouponGetWayEnum.APPOINT.getCode().equals(platformCouponDO.getGetWay())) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_RECEIVE_GET_WAY_ERROR);
        }
        // 剩余领取数需大于0
        if (platformCouponDO.getQuantity() - couponCacheComponent.getCouponObtainQuantity(BelongTypeEnum.PLATFORM, platformCouponDO.getId()) <= 0) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_SURPLUS_QUANTITY_ZERO);
        }

        return Wrapper.success();
    }

    /**
     * 校验平台优惠券的商城规则
     * @param platformCouponDO 平台优惠券
     * @param shopId 商城id
     * @return true, false
     */
    public boolean checkPlatformCouponShopRule(PlatformCouponDO platformCouponDO, Long shopId) {
        // 适用商城
        List<CouponShopDO> shopDOList = couponShopRepository.findByBelongTypeAndCouponId(BelongTypeEnum.PLATFORM.getCode(), platformCouponDO.getId());

        return shopDOList.stream().anyMatch(e -> e.getShopId().equals(shopId));
    }

    /**
     * 校验平台优惠券的会员领取记录规则
     * @param memberId 会员id
     * @param roleId 角色id
     * @param platformCouponDO 平台优惠券
     * @return true, false
     */
    public boolean checkPlatformMemberReceiveDetailRule(Long memberId, Long roleId, PlatformCouponDO platformCouponDO) {
        // 已领取的记录
        List<PlatformCouponDetailDO> platformCouponDetailDOList = platformCouponDetailRepository.findAllByCouponIdAndSubMemberIdAndSubRoleId(platformCouponDO.getId(), memberId, roleId);
        // 前台领券
        if (PlatformCouponGetWayEnum.FRONT.getCode().equals(platformCouponDO.getGetWay())) {
            // 总共可以领取数量
            if (platformCouponDO.getConditionGetTotal().equals(platformCouponDetailDOList.size())) {
                return false;
            }
            // 日可领取数量
            long count = platformCouponDetailDOList.stream().filter(e -> LocalDateTime.ofInstant(Instant.ofEpochMilli(e.getCreateTime()), ZoneId.systemDefault()).toLocalDate().compareTo(LocalDate.now()) == 0).count();
            if (count >= platformCouponDO.getConditionGetDay()) {
                return false;
            }
        } else {
            // 是否已领取
            if (!CollectionUtils.isEmpty(platformCouponDetailDOList)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 判断平台优惠券会员领取记录
     * 如果有领取且未使用,则会直接返回已领取
     * @param loginUser 登录会员信息
     * @param platformCouponDO 平台优惠券
     * @return -1 无法领取, 0 未领取, 1 已领取
     */
    public CanReceiveEnum checkPlatformReceiveDetailComplete(UserLoginCacheDTO loginUser, PlatformCouponDO platformCouponDO) {
        // 已领取的记录
        List<PlatformCouponDetailDO> platformCouponDetailDOList = platformCouponDetailRepository.findAllByCouponIdAndSubMemberIdAndSubRoleId(platformCouponDO.getId(), loginUser.getMemberId(), loginUser.getMemberRoleId());

        // 是否已领取
        if (!CollectionUtils.isEmpty(platformCouponDetailDOList)) {
            // 是否有未使用
            if (platformCouponDetailDOList.stream().anyMatch(e -> PlatformCouponDetailStatusEnum.RECEIVE.getCode().equals(e.getStatus()))) {
                return CanReceiveEnum.COMPLETE_RECEIVE;
            }
        }

        // 前台领券
        if (PlatformCouponGetWayEnum.FRONT.getCode().equals(platformCouponDO.getGetWay())) {
            // 总共可以领取数量
            if (platformCouponDO.getConditionGetTotal().equals(platformCouponDetailDOList.size())) {
                return CanReceiveEnum.NO_MATCH;
            }
            // 日可领取数量
            long count = platformCouponDetailDOList.stream().filter(e -> LocalDateTime.ofInstant(Instant.ofEpochMilli(e.getCreateTime()), ZoneId.systemDefault()).toLocalDate().compareTo(LocalDate.now()) == 0).count();
            if (count >= platformCouponDO.getConditionGetDay()) {
                return CanReceiveEnum.NO_MATCH;
            }
        }

        return CanReceiveEnum.CAN_RECEIVE;
    }

    /**
     * 检查平台优惠券的会员等级规则
     * @param platformCouponDO 平台优惠券
     * @param subMemberSuitableMemberVO 适用会员等级信息
     * @return 匹配到的适用会员
     */
    public PlatformSuitableMemberEnum checkPlatformMemberLevelRule(PlatformCouponDO platformCouponDO, PfSubMemberSuitableMemberVO subMemberSuitableMemberVO) {
        PlatformSuitableMemberEnum suitableMemberEnum = null;
        // 适用会员
        List<Integer> suitableMemberList = SuitableFieldComponent.parseCouponSuitableMember(platformCouponDO.getSuitableMember());
        if (suitableMemberList.contains(PlatformSuitableMemberEnum.NEW_PLATFORM_MEMBER.getCode()) && subMemberSuitableMemberVO.isNewMember()) {
            suitableMemberEnum = PlatformSuitableMemberEnum.NEW_PLATFORM_MEMBER;
        } else if (suitableMemberList.contains(PlatformSuitableMemberEnum.OLD_PLATFORM_MEMBER.getCode()) && subMemberSuitableMemberVO.isOldMember()) {
            suitableMemberEnum = PlatformSuitableMemberEnum.OLD_PLATFORM_MEMBER;
        } else {
            return null;
        }

        // 会员类型
        List<Integer> MemberTypeList = SuitableFieldComponent.parseMarketingMemberType(platformCouponDO.getSuitableMemberType());
        if (!MemberTypeList.contains(subMemberSuitableMemberVO.getMemberType())) {
            return null;
        }

        // 适用会员等级
        List<CouponMemberLevelDO> memberLevelDOList = couponMemberLevelRepository.findByBelongTypeAndCouponId(BelongTypeEnum.PLATFORM.getCode(), platformCouponDO.getId());
        if (!CollectionUtils.isEmpty(memberLevelDOList)) {
            if (!this.containsPlatformMemberLevel(memberLevelDOList, subMemberSuitableMemberVO)) {
                return null;
            }
        }

        return suitableMemberEnum;
    }

    // ===========================商家===========================

    /**
     * @see #baseCheckMerchantCanReceiveComplete
     */
    public CanReceiveEnum checkMerchantCanReceiveComplete(UserLoginCacheDTO loginUser, MerchantCouponDO merchantCouponDO, Long shopId, List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList) {
        AtCanReceiveSuitableMemberBO atCanReceiveSuitableMemberBO = this.baseCheckMerchantCanReceiveComplete(loginUser, merchantCouponDO, shopId, subMemberSuitableMemberVOList);
        return atCanReceiveSuitableMemberBO.getCanReceive();
    }

    /**
     * 校验商家优惠券是否可领取
     * 如果有领取且未使用,则会直接返回已领取
     * 如果登录了则会校验会员的等级规则,否则不校验
     * @param loginUser 登录用户信息
     * @param merchantCouponDO 商家优惠券
     * @param shopId 商城id
     * @param subMemberSuitableMemberVOList 会员等级信息
     * @return AtCanReceiveSuitableMemberBO 领取判断结果, 匹配到的适用会员
     */
    public AtCanReceiveSuitableMemberBO baseCheckMerchantCanReceiveComplete(UserLoginCacheDTO loginUser, MerchantCouponDO merchantCouponDO, Long shopId, List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList) {
        AtCanReceiveSuitableMemberBO atCanReceiveSuitableMemberBO = new AtCanReceiveSuitableMemberBO();
        // 是否登录
        if (Objects.isNull(loginUser)) {
            atCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_LOGIN);
            return atCanReceiveSuitableMemberBO;
        }

        // 判断优惠券基本规则
        if (!checkMerchantCouponBaseRule(merchantCouponDO)) {
            atCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return atCanReceiveSuitableMemberBO;
        }

        // 判断优惠券商城规则
        if (!checkMerchantCouponShopRule(merchantCouponDO, shopId)) {
            atCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return atCanReceiveSuitableMemberBO;
        }

        // 判断会员等级规则
        AbilitySuitableMemberEnum suitableMemberEnum = checkMerchantMemberLevelRule(loginUser.getMemberId(), loginUser.getMemberRoleId(), merchantCouponDO, subMemberSuitableMemberVOList);
        if (Objects.isNull(suitableMemberEnum)) {
            atCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return atCanReceiveSuitableMemberBO;
        }

        // 判断会员领取记录
        CanReceiveEnum canReceiveEnum = checkMerchantReceiveComplete(loginUser, merchantCouponDO);
        atCanReceiveSuitableMemberBO.setCanReceive(canReceiveEnum);
        atCanReceiveSuitableMemberBO.setSuitableMember(suitableMemberEnum);
        return atCanReceiveSuitableMemberBO;
    }

    /**
     * 校验商家优惠券是否可领取-【适用于营销活动赠券】
     * 如果有领取且未使用,则会直接返回已领取
     * 如果登录了则会校验会员的等级规则,否则不校验
     * @param loginUser 登录用户信息
     * @param merchantCouponDO 商家优惠券
     * @param shopId 商城id
     * @param subMemberSuitableMemberVOList 会员等级信息
     * @return AtCanReceiveSuitableMemberBO 领取判断结果, 匹配到的适用会员
     */
    public AtCanReceiveSuitableMemberBO baseCheckMerchantCanReceiveCompleteByActivity(UserLoginCacheDTO loginUser, MerchantCouponDO merchantCouponDO, Long shopId, List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList) {
        AtCanReceiveSuitableMemberBO atCanReceiveSuitableMemberBO = new AtCanReceiveSuitableMemberBO();
        // 是否登录
        if (Objects.isNull(loginUser)) {
            atCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_LOGIN);
            return atCanReceiveSuitableMemberBO;
        }

        // 判断优惠券基本规则
        if (!checkMerchantCouponBaseRule(merchantCouponDO,MerchantCouponGetWayEnum.MARKETING.getCode())) {
            atCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return atCanReceiveSuitableMemberBO;
        }

        // 判断优惠券商城规则
        if (!checkMerchantCouponShopRule(merchantCouponDO, shopId)) {
            atCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return atCanReceiveSuitableMemberBO;
        }

        // 判断会员等级规则
        AbilitySuitableMemberEnum suitableMemberEnum = checkMerchantMemberLevelRule(loginUser.getMemberId(), loginUser.getMemberRoleId(), merchantCouponDO, subMemberSuitableMemberVOList);
        if (Objects.isNull(suitableMemberEnum)) {
            atCanReceiveSuitableMemberBO.setCanReceive(CanReceiveEnum.NO_MATCH);
            return atCanReceiveSuitableMemberBO;
        }
        atCanReceiveSuitableMemberBO.setSuitableMember(suitableMemberEnum);
        return atCanReceiveSuitableMemberBO;
    }

    /**
     * 校验商家优惠券是否可领取
     * 如果登录了则会校验会员的等级规则,否则不校验
     * @param loginUser 登录用户信息
     * @param merchantCouponDO 商家优惠券
     * @param shopId 商城id
     * @param subMemberSuitableMemberVOList 会员等级信息
     * @return true, false
     */
    public boolean checkMerchantCanReceive(UserLoginCacheDTO loginUser, MerchantCouponDO merchantCouponDO, Long shopId, List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList) {
        // 是否登录
        if (Objects.isNull(loginUser)) {
            return false;
        }

        // 判断优惠券基本规则
        if (!checkMerchantCouponBaseRule(merchantCouponDO)) {
            return false;
        }

        // 判断优惠券商城规则
        if (!checkMerchantCouponShopRule(merchantCouponDO, shopId)) {
            return false;
        }

        // 判断会员等级规则
        AbilitySuitableMemberEnum suitableMemberEnum = checkMerchantMemberLevelRule(loginUser.getMemberId(), loginUser.getMemberRoleId(), merchantCouponDO, subMemberSuitableMemberVOList);
        if (Objects.isNull(suitableMemberEnum)) {
            return false;
        }
        // 判断会员领取记录
        return checkMerchantMemberReceiveDetailRule(loginUser.getMemberId(), loginUser.getMemberRoleId(), merchantCouponDO);
    }

    /**
     * 校验商家优惠券的基本规则(前台用户领取)
     * @param merchantCouponDO 商家优惠券
     * @return true, false
     */
    public boolean checkMerchantCouponBaseRule(MerchantCouponDO merchantCouponDO) {
        return checkMerchantCouponBaseRule(merchantCouponDO,MerchantCouponGetWayEnum.FRONT.getCode());
    }

    /**
     * 校验商家优惠券的基本规则(前台用户领取)
     * @param merchantCouponDO 商家优惠券
     * @return true, false
     */
    public boolean checkMerchantCouponBaseRule(MerchantCouponDO merchantCouponDO,Integer reqGetWay) {
        long currentTimeMillis = System.currentTimeMillis();
        // 进行中
        if (!MerchantCouponStatusEnum.EXECUTING.getCode().equals(merchantCouponDO.getStatus())) {
            return false;
        }
        // 在发券时间内
        if (merchantCouponDO.getReleaseTimeStart() > currentTimeMillis || merchantCouponDO.getReleaseTimeEnd() < currentTimeMillis) {
            return false;
        }
        // 领取方式
        if (!reqGetWay.equals(merchantCouponDO.getGetWay())) {
            return false;
        }
        //如果是前台用户，判断领取条件
        if(MerchantCouponGetWayEnum.FRONT.getCode().equals(reqGetWay)) {
            // 领取条件
            if (Objects.isNull(merchantCouponDO.getConditionGetTotal()) || Objects.isNull(merchantCouponDO.getConditionGetDay())) {
                return false;
            }
        }
        // 剩余领取数需大于0
        if (merchantCouponDO.getQuantity() - couponCacheComponent.getCouponObtainQuantity(BelongTypeEnum.MERCHANT, merchantCouponDO.getId()) <= 0) {
            return false;
        }

        return true;
    }

    /**
     * 校验商家优惠券的基本规则(指定会员领取)
     * @param merchantCouponDO 商家优惠券
     * @return true, false
     */
    public Wrapper<Void> checkMerchantAppointCouponBaseRule(MerchantCouponDO merchantCouponDO) {
        long currentTimeMillis = System.currentTimeMillis();
        // 进行中
        if (!MerchantCouponStatusEnum.EXECUTING.getCode().equals(merchantCouponDO.getStatus())) {
            return Wrapper.fail(ResponseCode.MARKETING_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        // 在发券时间内
        if (merchantCouponDO.getReleaseTimeStart() > currentTimeMillis || merchantCouponDO.getReleaseTimeEnd() < currentTimeMillis) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_CURRENT_TIME_NOT_IN_RELEASE_TIME);
        }
        // 指定会员领取
        if (!MerchantCouponGetWayEnum.APPOINT.getCode().equals(merchantCouponDO.getGetWay())) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_RECEIVE_GET_WAY_ERROR);
        }
        // 剩余领取数需大于0
        if (merchantCouponDO.getQuantity() - couponCacheComponent.getCouponObtainQuantity(BelongTypeEnum.MERCHANT, merchantCouponDO.getId()) <= 0) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_SURPLUS_QUANTITY_ZERO);
        }

        return Wrapper.success();
    }

    /**
     * 校验商家优惠券的商城规则
     * @param merchantCouponDO 平台优惠券
     * @param shopId 商城id
     * @return true, false
     */
    public boolean checkMerchantCouponShopRule(MerchantCouponDO merchantCouponDO, Long shopId) {
        // 适用商城
        List<CouponShopDO> shopDOList = couponShopRepository.findByBelongTypeAndCouponId(BelongTypeEnum.MERCHANT.getCode(), merchantCouponDO.getId());

        return shopDOList.stream().anyMatch(e -> e.getShopId().equals(shopId));
    }

    /**
     * 校验商家优惠券的会员领取记录规则
     * @param memberId 会员id
     * @param roleId 角色id
     * @param merchantCouponDO 商家优惠券
     * @return true, false
     */
    public boolean checkMerchantMemberReceiveDetailRule(Long memberId, Long roleId, MerchantCouponDO merchantCouponDO) {
        // 已领取的记录
        List<MerchantCouponDetailDO> merchantCouponDetailDOList = merchantCouponDetailRepository.findAllByCouponIdAndSubMemberIdAndSubRoleId(merchantCouponDO.getId(), memberId, roleId);
        if (MerchantCouponGetWayEnum.FRONT.getCode().equals(merchantCouponDO.getGetWay())) {
            // 总共可以领取数量
            if (merchantCouponDO.getConditionGetTotal().equals(merchantCouponDetailDOList.size())) {
                return false;
            }
            // 日可领取数量
            long count = merchantCouponDetailDOList.stream().filter(e -> LocalDateTime.ofInstant(Instant.ofEpochMilli(e.getCreateTime()), ZoneId.systemDefault()).toLocalDate().compareTo(LocalDate.now()) == 0).count();
            if (count >= merchantCouponDO.getConditionGetDay()) {
                return false;
            }
        } else {
            // 是否已领取
            if (!CollectionUtils.isEmpty(merchantCouponDetailDOList)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 判断商家优惠券会员领取记录
     * @param loginUser 登录会员信息
     * @param merchantCouponDO 商家优惠券
     * @return CanReceiveEnum 判断结果
     */
    public CanReceiveEnum checkMerchantReceiveComplete(UserLoginCacheDTO loginUser, MerchantCouponDO merchantCouponDO) {
        // 已领取的记录
        List<MerchantCouponDetailDO> merchantCouponDetailDOList = merchantCouponDetailRepository.findAllByCouponIdAndSubMemberIdAndSubRoleId(merchantCouponDO.getId(), loginUser.getMemberId(), loginUser.getMemberRoleId());
        // 是否已领取
        if (!CollectionUtils.isEmpty(merchantCouponDetailDOList)) {
            // 是否有未使用
            if (merchantCouponDetailDOList.stream().anyMatch(e -> PlatformCouponDetailStatusEnum.RECEIVE.getCode().equals(e.getStatus()))) {
                return CanReceiveEnum.COMPLETE_RECEIVE;
            }
        }


        if (MerchantCouponGetWayEnum.FRONT.getCode().equals(merchantCouponDO.getGetWay())) {
            // 总共可以领取数量
            if (merchantCouponDO.getConditionGetTotal().equals(merchantCouponDetailDOList.size())) {
                return CanReceiveEnum.NO_MATCH;
            }
            // 日可领取数量
            long count = merchantCouponDetailDOList.stream().filter(e -> LocalDateTime.ofInstant(Instant.ofEpochMilli(e.getCreateTime()), ZoneId.systemDefault()).toLocalDate().compareTo(LocalDate.now()) == 0).count();
            if (count >= merchantCouponDO.getConditionGetDay()) {
                return CanReceiveEnum.NO_MATCH;
            }
        }

        return CanReceiveEnum.CAN_RECEIVE;
    }

    /**
     * 检查商家优惠券的会员等级规则
     * @param memberId 当前登录的会员id
     * @param roleId 当前登录的会员角色id
     * @param merchantCouponDO 平台优惠券
     * @param subMemberSuitableMemberVOList 适用会员等级信息
     * @return 匹配到的适用会员
     */
    public AbilitySuitableMemberEnum checkMerchantMemberLevelRule(Long memberId, Long roleId, MerchantCouponDO merchantCouponDO, List<AtSubMemberSuitableMemberVO> subMemberSuitableMemberVOList) {
        // 查找会员关系
        AtSubMemberSuitableMemberVO subMemberSuitableMemberVO = subMemberSuitableMemberVOList.stream()
                .filter(e -> merchantCouponDO.getMemberId().equals(e.getUpperMemberId())
                        && merchantCouponDO.getRoleId().equals(e.getUpperRoleId())
                        && memberId.equals(e.getMemberId())
                        && roleId.equals(e.getRoleId())
                )
                .findFirst()
                .orElse(null);
        if (Objects.isNull(subMemberSuitableMemberVO)) {
            return null;
        }

        AbilitySuitableMemberEnum suitableMemberEnum = null;
        // 适用会员
        List<Integer> suitableUserList = SuitableFieldComponent.parseCouponSuitableUser(merchantCouponDO.getSuitableUser());
        // 是否为下级会员
        if (subMemberSuitableMemberVO.isSubMemberRelation()) {
            if (suitableUserList.contains(AbilitySuitableMemberEnum.NEW_MEMBER.getCode()) && subMemberSuitableMemberVO.isNewMember()) {
                suitableMemberEnum = AbilitySuitableMemberEnum.NEW_MEMBER;
            } else if (suitableUserList.contains(AbilitySuitableMemberEnum.OLD_MEMBER.getCode()) && subMemberSuitableMemberVO.isOldMember()) {
                suitableMemberEnum = AbilitySuitableMemberEnum.OLD_MEMBER;
            } else {
                return null;
            }

            // 判断适用会员等级
            List<CouponMemberLevelDO> memberLevelDOList = couponMemberLevelRepository.findByBelongTypeAndCouponId(BelongTypeEnum.MERCHANT.getCode(), merchantCouponDO.getId());
            if (!CollectionUtils.isEmpty(memberLevelDOList)) {
                if (!this.containsAbilityMemberLevel(memberLevelDOList, subMemberSuitableMemberVO)) {
                    return null;
                }
            }

        } else {
            if (suitableUserList.contains(AbilitySuitableMemberEnum.NEW_USER.getCode()) && subMemberSuitableMemberVO.isNewUser()) {
                suitableMemberEnum = AbilitySuitableMemberEnum.NEW_USER;
            } else if (suitableUserList.contains(AbilitySuitableMemberEnum.OLD_USER.getCode()) && subMemberSuitableMemberVO.isOldUser()) {
                suitableMemberEnum = AbilitySuitableMemberEnum.OLD_USER;
            } else {
                return null;
            }
        }

        return suitableMemberEnum;
    }

    // ===========================公共===========================

    /**
     * 是否符合会员类型, 会员角色, 会员等级类型, 会员等级
     * @param memberLevelDOList 会员等级配置
     * @param subMemberSuitableMemberVO 会员关系
     * @return true, false
     */
    private boolean containsAbilityMemberLevel(List<CouponMemberLevelDO> memberLevelDOList, AtSubMemberSuitableMemberVO subMemberSuitableMemberVO) {
        for (CouponMemberLevelDO couponMemberLevelDO : memberLevelDOList) {
            // 会员类型, 会员角色, 会员等级类型, 会员等级
            if (couponMemberLevelDO.getMemberType().equals(subMemberSuitableMemberVO.getMemberType())
                    && couponMemberLevelDO.getRoleType().equals(subMemberSuitableMemberVO.getRoleType())
                    && couponMemberLevelDO.getRoleId().equals(subMemberSuitableMemberVO.getRoleId())
                    && couponMemberLevelDO.getLevelType().equals(subMemberSuitableMemberVO.getLevelType())
                    && couponMemberLevelDO.getLevel().equals(subMemberSuitableMemberVO.getLevel())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否符合会员类型, 会员角色, 会员等级类型, 会员等级
     * @param memberLevelDOList 会员等级配置
     * @param subMemberSuitableMemberVO 会员关系
     * @return true, false
     */
    private boolean containsPlatformMemberLevel(List<CouponMemberLevelDO> memberLevelDOList, PfSubMemberSuitableMemberVO subMemberSuitableMemberVO) {
        for (CouponMemberLevelDO couponMemberLevelDO : memberLevelDOList) {
            // 会员类型, 会员角色, 会员等级类型, 会员等级
            if (couponMemberLevelDO.getMemberType().equals(subMemberSuitableMemberVO.getMemberType())
                    && couponMemberLevelDO.getRoleType().equals(subMemberSuitableMemberVO.getRoleType())
                    && couponMemberLevelDO.getRoleId().equals(subMemberSuitableMemberVO.getRoleId())
                    && couponMemberLevelDO.getLevelType().equals(subMemberSuitableMemberVO.getLevelType())
                    && couponMemberLevelDO.getLevel().equals(subMemberSuitableMemberVO.getLevel())) {
                return true;
            }
        }

        return false;
    }

}

